package com.ghp.search.manager;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ghp.search.common.ErrorCode;
import com.ghp.search.datasource.*;
import com.ghp.search.exception.ThrowUtils;
import com.ghp.search.model.dto.search.SearchRequest;
import com.ghp.search.model.entity.Picture;
import com.ghp.search.model.enums.SearchTypeEnum;
import com.ghp.search.model.vo.PostVO;
import com.ghp.search.model.vo.SearchVO;
import com.ghp.search.model.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.CompletableFuture;

/**
 * @author ghp
 * @date 2023/5/31
 * @title
 * @description
 */
@Component
@Slf4j
public class SearchFacade {

    @Resource
    private PostDataSource postDataSource;

    @Resource
    private PictureDataSource pictureDataSource;

    @Resource
    private UserDataSource userDataSource;

    @Resource
    private DataSourceRegistry dataSourceRegistry;

    public SearchVO searchAll(@RequestBody SearchRequest searchRequest, HttpServletRequest request) {
        // 获取请求参数
        String searchText = searchRequest.getSearchText();
        String type = searchRequest.getType();
        long pageNum = searchRequest.getCurrent();
        long pageSize = searchRequest.getPageSize();

        // 根据type查询对应的数据
        SearchVO searchVO = new SearchVO();
        if (type == null) {
            // type为空，查询所有数据

            // 文章查询线程任务
            CompletableFuture<Page<PostVO>> postTask = CompletableFuture.supplyAsync(() ->
                    postDataSource.doSearch(searchText, pageNum, pageSize));

            // 图片查询线程任务
            CompletableFuture<Page<Picture>> pictureTask = CompletableFuture.supplyAsync(() ->
                    pictureDataSource.doSearch(searchText, pageNum, pageSize));

            // 用户查询线程任务
            CompletableFuture<Page<UserVO>> userTask = CompletableFuture.supplyAsync(() ->
                    userDataSource.doSearch(searchText, pageNum, pageSize));

            // 三个任务都执行完毕才执行后面的代码（join方法相当于一个断点）
            CompletableFuture.allOf(postTask, pictureTask, userTask).join();
            // 获取线程任务的执行结果
            Page<PostVO> postVOPage = null;
            Page<Picture> picturePage = null;
            Page<UserVO> userVOPage = null;
            try {
                postVOPage = postTask.get();
                picturePage = pictureTask.get();
                userVOPage = userTask.get();
            } catch (Exception e) {
                log.error("聚合查询发生异常");
                throw new RuntimeException(e);
            }

            // 响应结果
            searchVO.setPostList(postVOPage.getRecords());
            searchVO.setPictureList(picturePage.getRecords());
            searchVO.setUserList(userVOPage.getRecords());
            return searchVO;

        } else {
            // type 不为空，先判断type是否合法，合法则查询对应的数据
            SearchTypeEnum searchType = SearchTypeEnum.getEnumByValue(type);
            ThrowUtils.throwIf(searchType == null, ErrorCode.PARAMS_ERROR);
            DataSource dataSource = dataSourceRegistry.getDataSourceByType(type);
            Page<?> page = dataSource.doSearch(searchText, pageNum, pageSize);
            searchVO.setDataList(page.getRecords());
            return searchVO;
        }

    }
}
